﻿using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Xmart.Infrastructures.Office.Helpers;
using Xms.Abp.Application.Dtos;
using Xms.Abp.Application.Services;

namespace Xms.Abp.AspNetCore.Mvc;

public abstract class XmsCrudController<TService, TEntityDto, TKey>
    : XmsCrudController<TService, TEntityDto, TKey, PagedSortedAndFilterParameter>,
    IXmsCrudAppService<TEntityDto, TKey>
    where TService : IXmsCrudAppService<TEntityDto, TKey>
    where TEntityDto : IEntityDto<TKey>
{

}
public abstract class XmsCrudController<TService, TEntityDto, TKey, TPagedParameter>
    : XmsCrudController<TService, TEntityDto, TKey, TPagedParameter, TEntityDto>,
    IXmsCrudAppService<TEntityDto, TKey, TPagedParameter>
    where TService : IXmsCrudAppService<TEntityDto, TKey, TPagedParameter>
    where TEntityDto : IEntityDto<TKey>
    where TPagedParameter : class, IPagedSortedAndFilterParameter
{

}
public abstract class XmsCrudController<TService, TEntityDto, TKey, TPagedParameter, TCreateParameter>
    : XmsCrudController<TService, TEntityDto, TKey, TPagedParameter, TCreateParameter, TCreateParameter>,
    IXmsCrudAppService<TEntityDto, TKey, TPagedParameter, TCreateParameter>
    where TService : IXmsCrudAppService<TEntityDto, TKey, TPagedParameter, TCreateParameter>
    where TEntityDto : IEntityDto<TKey>
    where TPagedParameter : class, IPagedSortedAndFilterParameter
{

}
public abstract class XmsCrudController<TService, TEntityDto, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    : XmsCrudController<TService, TEntityDto, TEntityDto, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>,
    IXmsCrudAppService<TEntityDto, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    where TService : IXmsCrudAppService<TEntityDto, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    where TEntityDto : IEntityDto<TKey>
    where TPagedParameter : class, IPagedSortedAndFilterParameter
{

}

public abstract class XmsCrudController<TService, TDetailsResult, TPagingListResult, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    : XmsCrudController<TService, TDetailsResult, TPagingListResult, TDetailsResult, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>,
    IXmsCrudAppService<TDetailsResult, TPagingListResult, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    where TService : IXmsCrudAppService<TDetailsResult, TPagingListResult, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    where TDetailsResult : IEntityDto<TKey>
    where TPagingListResult : IEntityDto<TKey>
    where TPagedParameter : class, IPagedSortedAndFilterParameter
{

}
public abstract class XmsCrudController<TService, TDetailsResult, TPagingListResult, TExportResult, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    : XmsCrudController<TService, TDetailsResult, TPagingListResult, TExportResult, TExportResult, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>,
    IXmsCrudAppService<TDetailsResult, TPagingListResult, TExportResult, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    where TService : IXmsCrudAppService<TDetailsResult, TPagingListResult, TExportResult, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    where TDetailsResult : IEntityDto<TKey>
    where TPagingListResult : IEntityDto<TKey>
    where TPagedParameter : class, IPagedSortedAndFilterParameter
{

}
public abstract class XmsCrudController<TService, TDetailsResult, TPagingListResult, TExportResult, TImportParameter, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    : XmsController<TService>,
    IXmsCrudAppService<TDetailsResult, TPagingListResult, TExportResult, TImportParameter, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    where TService : IXmsCrudAppService<TDetailsResult, TPagingListResult, TExportResult, TImportParameter, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>
    where TDetailsResult : IEntityDto<TKey>
    where TPagingListResult : IEntityDto<TKey>
    where TPagedParameter : class, IPagedSortedAndFilterParameter
{
    [HttpPost]
    [Route("create")]
    [SwaggerOperation("创建")]
    public virtual async Task<TDetailsResult> CreateAsync(TCreateParameter input)
        => await CurrentService.CreateAsync(input);

    [HttpPut]
    [Route("{id}/update")]
    [SwaggerOperation("修改")]
    public virtual async Task<TDetailsResult> UpdateAsync([SwaggerParameter("主键ID")]TKey id, TUpdateParameter input)
        => await CurrentService.UpdateAsync(id, input);

    [HttpGet]
    [Route("{id}")]
    [SwaggerOperation("获取详情")]
    public virtual async Task<TDetailsResult> GetAsync(TKey id)
        => await CurrentService.GetAsync(id);

    [HttpGet]
    [Route("by/no/{no}")]
    [SwaggerOperation("获取详情")]
    public virtual async Task<TDetailsResult> GetAsync(string no)
        => await CurrentService.GetAsync(no);

    [HttpPost]
    [Route("page")]
    [SwaggerOperation("获取分页列表数据")]
    public virtual async Task<PagedResult<TPagingListResult>> GetListAsync(TPagedParameter input)
        => await CurrentService.GetListAsync(input);

    async Task<PagedResultDto<TPagingListResult>> IReadOnlyAppService<TDetailsResult, TPagingListResult, TKey, TPagedParameter>.GetListAsync(TPagedParameter input)
        => await CurrentService.GetListAsync(input);

    [HttpDelete]
    [Route("{id}/delete")]
    [SwaggerOperation("删除")]
    public virtual async Task DeleteAsync([SwaggerParameter("主键ID")]TKey id)
        => await CurrentService.DeleteAsync(id);

    [HttpPost]
    [Route("delete")]
    [SwaggerOperation("批量删除")]
    public virtual async Task DeleteAsync([SwaggerParameter("主键ID集合")]TKey[] ids)
        => await CurrentService.DeleteAsync(ids);

    [HttpPost]
    [Route("export")]
    [SwaggerOperation("导出")]
    public virtual async Task<FileResult> ExportAsync(TPagedParameter input)
    {
        var (bytes, fileName) = await CurrentService.ExportAsync(input);
        return ExportAsync(bytes, fileName);
    }

    [HttpPost]
    [Route("import")]
    [SwaggerOperation("导入")]
    public virtual async Task<object> ImportAsync()
    {
        var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "uploads", DateTime.Now.ToString("yyyyMMdd"));
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        var file = Path.Combine(path, Guid.NewGuid().ToString("n") + ".xlsx");
        using (var fStream = new FileStream(file, FileMode.Create, FileAccess.Write))
        {
            await Request.Form.Files[0].CopyToAsync(fStream);
            fStream.Seek(0, SeekOrigin.Begin);
        }
        await CurrentService.ImportAsync(file);
        return new { success = true };
    }

    [HttpPost]
    [Route("templet")]
    [SwaggerOperation("下载导入模板")]
    public virtual async Task<FileResult> TempletAsync()
    {
        var type = typeof(TImportParameter);
        var attr = type.GetCustomAttribute<SheetAttribute>();
        var bytes = await CurrentService.TempletAsync();
        return ExportAsync(bytes, (attr?.SheetName ?? type.Name) + "数据导入模板.xlsx");
    }

    [HttpPut]
    [Route("{id}/enabled/toggle")]
    [SwaggerOperation("切换启用禁用")]
    public virtual async Task ToggleEnabledAsync([SwaggerParameter("主键ID")]TKey id, [SwaggerParameter("是否启用")][FromQuery]bool isEnabled)
        => await CurrentService.ToggleEnabledAsync(id, isEnabled);

    [HttpGet]
    [Route("name-values")]
    [SwaggerOperation("获取下拉字典数据，Id-Name")]
    public virtual async Task<List<NameValue<TKey>>> GetNameValuesAsync([SwaggerParameter("过滤条件")][FromQuery] string filter = null)
        => await CurrentService.GetNameValuesAsync(filter);

    [HttpGet]
    [Route("name-nos")]
    [SwaggerOperation("获取下拉字典数据，No-Name")]
    public virtual async Task<List<NameValue>> GetNameNosAsync([SwaggerParameter("过滤条件")][FromQuery] string filter = null)
        => await CurrentService.GetNameNosAsync(filter);

    [HttpPut]
    [Route("{id}/submit/review")]
    [SwaggerOperation("提交审核")]
    public virtual async Task SubmitReviewAsync(TKey id)
        => await CurrentService.SubmitReviewAsync(id);

    [HttpPut]
    [Route("{id}/review")]
    [SwaggerOperation("审核")]
    public virtual async Task ReviewAsync(TKey id, ReviewParameter parameter)
        => await CurrentService.ReviewAsync(id, parameter);

    Task IXmsCrudAppService<TDetailsResult, TPagingListResult, TExportResult, TImportParameter, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>.ImportAsync(string file)
    {
        throw new NotImplementedException();
    }

    Task<(byte[], string)> IXmsCrudAppService<TDetailsResult, TPagingListResult, TExportResult, TImportParameter, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>.ExportAsync(TPagedParameter input)
    {
        throw new NotImplementedException();
    }

    Task<byte[]> IXmsCrudAppService<TDetailsResult, TPagingListResult, TExportResult, TImportParameter, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>.TempletAsync()
    {
        throw new NotImplementedException();
    }

    Task<TDetailsResult> IXmsCrudAppService<TDetailsResult, TPagingListResult, TExportResult, TImportParameter, TKey, TPagedParameter, TCreateParameter, TUpdateParameter>.ToggleEnabledAsync(TKey id, bool isEnabled)
    {
        throw new NotImplementedException();
    }
}
